package com.clay.appointment.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.clay.appointment.common.annotation.EnableAutoFillField;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * MybatisPlus 配置类
 * </p>
 *
 * @author Yohann
 * @since 2020/9/21
 */
@Slf4j
@Configuration
@EnableTransactionManagement
@MapperScan(Constants.MYBATIS_SCAN)
public class MyBatisPlusConfig {
    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /**
     * 乐观锁
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * 自动填充拦截器
     */
    @Bean
    public MetaObjectHandler getMetaObjectHandler() {
        return new MyMetaObjectHandler();
    }

    private static class MyMetaObjectHandler implements MetaObjectHandler {

        @Override
        public void insertFill(MetaObject metaObject) {
            for (String insertField : Constants.INSERT_FILL_FIELD) {
                setFieldValByName(insertField, new Date(), metaObject);
            }
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            for (String updateField : Constants.UPDATE_FILL_FIELD) {
                setFieldValByName(updateField, new Date(), metaObject);
            }
        }

        /**
         * 重写插入方法
         * 当前存在值则不插入
         */
        @Override
        public MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
            if (!metaObject.getOriginalObject().getClass().isAnnotationPresent(EnableAutoFillField.class)) {
                return this;
            }

            if (metaObject.hasGetter(fieldName)) {
                //当前存在值则不插入
                if (Constants.ALWAYS_FILL_FIELD || Objects.isNull(metaObject.getValue(fieldName))) {
                    if (metaObject.hasSetter(fieldName)) {
                        metaObject.setValue(fieldName, fieldVal);
                    }
                }
            }
            return this;
        }
    }
}